NLLLoss

负对数似然损失(Negative Log Likelihood Loss)。输入为对数概率 log_probs 与标签 labels,按类别权重 weight 计算逐样本损失,再按 reduction_type 归约。

设 batch 大小为 \(N\),类别数为 \(C\)log_probs 形状为 \(N \times C\)labels / 逐样本损失长度为 \(N\)weight 长度为 \(C\)

对样本 \(i\)

\[\ell_i = -\mathrm{log\_probs}[i, y_i] \cdot \mathrm{weight}[y_i]\]

其中 \(y_i = \mathrm{labels}[i]\)。同时:

\[W = \sum_{i=0}^{N-1} \mathrm{weight}[y_i],\quad L = \sum_{i=0}^{N-1} \ell_i\]

reduction_type

  • 0:None,写出逐样本 \(\ell_i\),输出长度 \(N\)

  • 1:Sum,loss[0]\(L\)

  • 2:Mean,loss[0]\(L / W\);若 \(W = 0\) 则写 0

total_weight 始终写回 \(W\)

输入:
  • log_probs - 对数概率地址,形状 [batch_size, class_num]

  • labels - 标签索引地址,形状 [batch_size],元素为 int

  • weight - 类别权重地址,形状 [class_num]

  • params - long long 参数数组,长度至少 3,布局见下

  • core_mask - 核掩码(仅共享存储版本使用)

params 布局:

  • [0] batch_size - batch 大小 \(N\)

  • [1] class_num - 类别数 \(C\)

  • [2] reduction_type - 归约方式,取值 {0,1,2}

输出:
  • loss - 损失地址;None 时长度 \(N\),Sum / Mean 时使用 loss[0]

  • total_weight - 权重和 \(W\) 的地址

支持平台:

FT78NE MT7004

备注

  • FT78NE 支持 int8、fp32

  • MT7004 支持 fp16、fp32

  • log_probs 应为已取对数的概率;labels[i] 需满足 \(0 \le y_i < C\)

  • 本 DSP 接口的 reduction_type0/1/2``(None / Sum / Mean),与 schema ``Reduction 枚举数值不完全相同

共享存储版本:

void i8_nll_loss_s(const int8_t *log_probs, const int *labels, const int8_t *weight, int32_t *loss, int32_t *total_weight, long long *params, int core_mask)
void hp_nll_loss_s(const float16 *log_probs, const int *labels, const float16 *weight, float16 *loss, float16 *total_weight, long long *params, int core_mask)
void fp_nll_loss_s(const float *log_probs, const int *labels, const float *weight, float *loss, float *total_weight, long long *params, int core_mask)

C调用示例:

 1// MT7004 示例(共享存储多核,DDR 地址)
 2void TestNllLossSMCFp32(int core_mask) {
 3    int core_id = get_core_id();
 4    int logic_core_id = GetLogicCoreId(core_mask, core_id);
 5    int core_num = GetCoreNum(core_mask);
 6    float *log_probs = (float *)0x81000000;
 7    int *labels = (int *)0x82000000;
 8    float *weight = (float *)0x83000000;
 9    float *loss = (float *)0x84000000;
10    float *total_weight = (float *)0x85000000;
11    long long params[3];
12    params[0] = 16; // batch_size
13    params[1] = 16; // class_num
14    params[2] = 0;  // reduction_type = None
15    sys_bar(0, core_num);
16    fp_nll_loss_s(log_probs, labels, weight, loss, total_weight, params, core_mask);
17}
18
19void main() {
20    int core_mask = 0b1111;
21    TestNllLossSMCFp32(core_mask);
22}

私有存储版本:

void i8_nll_loss_p(const int8_t *log_probs, const int *labels, const int8_t *weight, int32_t *loss, int32_t *total_weight, long long *params)
void hp_nll_loss_p(const float16 *log_probs, const int *labels, const float16 *weight, float16 *loss, float16 *total_weight, long long *params)
void fp_nll_loss_p(const float *log_probs, const int *labels, const float *weight, float *loss, float *total_weight, long long *params)

C调用示例:

 1// MT7004 示例(私有存储单核,AM 地址)
 2void TestNllLossAMFp32(void) {
 3    float *log_probs = (float *)0x10010000;
 4    int *labels = (int *)0x10020000;
 5    float *weight = (float *)0x10030000;
 6    float *loss = (float *)0x10040000;
 7    float *total_weight = (float *)0x10050000;
 8    long long params[3];
 9    params[0] = 16; // batch_size
10    params[1] = 16; // class_num
11    params[2] = 0;  // reduction_type = None
12    fp_nll_loss_p(log_probs, labels, weight, loss, total_weight, params);
13}
14
15void main() {
16    TestNllLossAMFp32();
17}